#include"common_headers.h"

int isValidPath(char pathname[300],struct narytree *temp)
{
	if(strncmp(pathname,temp->mydes->locationpath,strlen(temp->mydes->locationpath))==0 && (temp==nroot || pathname[strlen(temp->mydes->locationpath)]=='/'))
		return 1;
	else
		return 0;
}

struct narytree * memAllocNode()
{
	struct narytree *temp;
	temp=(struct narytree *)malloc(sizeof(struct narytree));
	temp->mydes=NULL;
        temp->child=NULL;
        temp->rightsibling=NULL;
        temp->leftsibling=NULL;
	temp->parent=NULL;
	return (temp);
}


int rightChildCheck(struct narytree *temp)
{
	int flag;

	if(temp->rightsibling==NULL)
	{
		flag=1;
	}	
	else if(temp->rightsibling!=NULL)
	{
		flag=2;
	}

return flag;

}

int leftChildCheck(struct narytree *temp)
{
	int flag;

	if(temp->leftsibling==NULL)
	{
		flag=1;
	}	
	else if(temp->leftsibling!=NULL)
	{
		flag=2;
	}

return flag;

}

int pathCompare(char source_dir_path[locationpath_size],struct narytree *temp)
{
	int flag;
	if(strcmp(source_dir_path,temp->mydes->locationpath)==0)
	{
		flag=1;
	}
	if(strcmp(source_dir_path,temp->mydes->locationpath)!=0)
	{
		flag=2;
	}
	
return flag;

}



int movedir31(char source_dir_path[locationpath_size],char dest_dir_path[locationpath_size])
{
    int valid,rightvalid,leftvalid,comparepath,is_mounted=0, collect=0;

	is_mounted = validateMountState();
	if(is_mounted)
	{
		if(strcmp(dest_dir_path,"")!=0)
		{
			 if(strcmp(source_dir_path,"")!=0)
    			 {
				if(search_nary(source_dir_path)!=0)
    				{
				     if(searched_Descriptor->filetype!="file")
    				     {
						
        				if(search_nary(dest_dir_path)!=0)
    					{
        					
        					if(searched_Descriptor->filetype!="file")
    						{
							if(strncmp(source_dir_path,dest_dir_path,strlen(source_dir_path))!=0)
   							 {
        							struct narytree *temp,*newadd;
    								temp=nroot;
    								if(temp==NULL) return 0;
   								else
    								{
									comparepath=pathCompare(source_dir_path,temp);

        								if(comparepath!=1)
        								{
									    
									    while(1)
									    {

										valid=isValidPath(source_dir_path,temp);
		
										comparepath=pathCompare(source_dir_path,temp);

										if(valid)
										{
										    if(temp->child==NULL)
										    {

											printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_01);
											return 0;
										    }

										    else
										    {

											temp=temp->child;
										    }
										}
										else if(comparepath==2)
										{

											rightvalid=rightChildCheck(temp);

											if(rightvalid==1)
											{
										    		printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_01);
										    		return 0;
											}
		
											else if(rightvalid==2)
									       		 {

										    		temp=temp->rightsibling;
											 }
										}



										if(comparepath==1)
										{


										    if((temp->parent!=NULL) )
										    {
											rightvalid=rightChildCheck(temp);

											if(rightvalid==1)
											{
												leftvalid=leftChildCheck(temp);

												if(leftvalid==2)
												{
												char errorhandling[locationpath_size];
												strcpy(errorhandling,dest_dir_path);
												if(strcmp(errorhandling,"/")!=0)
										       	 	{
											    		strcat(errorhandling,"/");
												}
												strcat(errorhandling,temp->mydes->filename);
												int find=search_nary(errorhandling);
												if(find==1)
												{
											    		printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_06);
											    		return 0;
												}
												struct narytree *tempo;
										   		tempo=memAllocNode();
						
												temp->leftsibling->rightsibling=NULL;
												tempo->mydes=temp->mydes;
										       

												if(temp->child!=NULL)
												{
											   		tempo->child=temp->child;
											    //temp->child->parent=NULL;
											    		tempo->child->parent=tempo;
											    		struct narytree *tempextra;
											    		tempextra=tempo->child;
													rightvalid=rightChildCheck(tempextra);
											   		 while(rightvalid==2)
											    		{
														tempextra->rightsibling->parent=tempo;
														tempextra=tempextra->rightsibling;
											    		}
												}
												else tempo->child=NULL;
										       		delete_bstnode(bst_root,temp->mydes->locationpath);////////////////

												free(temp);/////////////////////////


												if(strcmp(dest_dir_path,"/")!=0)
												{
											    		strcat(dest_dir_path,"/");
												}

												strcat(dest_dir_path,tempo->mydes->filename);
												strcpy(tempo->mydes->locationpath,dest_dir_path);
												int state=move_nary(tempo);///////////////////////////////////////////////
										       		if(state==1) 
												{
													printf("movedir_SUCCESS\n");
													
										       		return 1;
											    }
											}
												if(leftvalid==1)
												{
													char errorhandling[locationpath_size];
													strcpy(errorhandling,dest_dir_path);
													if(strcmp(errorhandling,"/")!=0)
										       			 {
											   			strcat(errorhandling,"/");
													 }
													strcat(errorhandling,temp->mydes->filename);
													int find=search_nary(errorhandling);
													if(find==1)
													{
											    			printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_06);
											    			return 0;
													}
													struct narytree *tempo;
													tempo=memAllocNode();
													temp->parent->child=NULL;
													tempo->mydes=temp->mydes;
										       
													if(temp->child!=NULL)
													{
											    //temp->child->parent=NULL;
											  			tempo->child=temp->child;
											    			tempo->child->parent=tempo;

											    			struct narytree *tempextra;
											    			tempextra=tempo->child;
														rightvalid=rightChildCheck(tempextra);
											   			 while(rightvalid==2)
											    			{
											       				 tempextra->rightsibling->parent=tempo;
															 tempextra=tempextra->rightsibling;
											    			}

													}

												       else {
														tempo->child=NULL;
													}	
													delete_bstnode(bst_root,temp->mydes->locationpath);
										       			free(temp);
													if(strcmp(dest_dir_path,"/")!=0)
													{
													    strcat(dest_dir_path,"/");
													}
													strcat(dest_dir_path,tempo->mydes->filename);
													strcpy(tempo->mydes->locationpath,dest_dir_path);

													int state=move_nary(tempo);
													if(state==1) printf("movedir_SUCCESS\n");
													return 1;
												}	
											}	
										    else if(rightvalid==2)
										    {
											leftvalid=leftChildCheck(temp);

											if(leftvalid==2)
											{
											char errorhandling[locationpath_size];
											strcpy(errorhandling,dest_dir_path);
											if(strcmp(errorhandling,"/")!=0)
											{
											    strcat(errorhandling,"/");
											}
											strcat(errorhandling,temp->mydes->filename);
											int find=search_nary(errorhandling);
											if(find==1)
											{
											    printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_06);
											    return 0;
											}
											struct narytree *tempo;
											tempo=memAllocNode();

											temp->leftsibling->rightsibling=temp->rightsibling;
											temp->rightsibling->leftsibling=temp->leftsibling;
											tempo->mydes=temp->mydes;
						
											if(temp->child!=NULL)
											{
											    //temp->child->parent=NULL;
											    tempo->child=temp->child;
											    tempo->child->parent=tempo;
											    struct narytree *tempextra;
											    tempextra=tempo->child;
											    rightvalid=rightChildCheck(tempextra);
											    while(rightvalid==2)
											    {
												tempextra->rightsibling->parent=tempo;
												tempextra=tempextra->rightsibling;
											    }
											}
											else tempo->child=NULL;


											delete_bstnode(bst_root,temp->mydes->locationpath);
											free(temp);
											if(strcmp(dest_dir_path,"/")!=0)
											{
											    strcat(dest_dir_path,"/");
											}
											strcat(dest_dir_path,tempo->mydes->filename);
											strcpy(tempo->mydes->locationpath,dest_dir_path);
											int state=move_nary(tempo);
											if(state==1) printf("movedir_SUCCESS\n");
											return 1;
										    }

										    else if(leftvalid==1)
										    {
											char errorhandling[locationpath_size];
											strcpy(errorhandling,dest_dir_path);
											if(strcmp(errorhandling,"/")!=0)
											{
											    strcat(errorhandling,"/");
											}
											strcat(errorhandling,temp->mydes->filename);
											int find=search_nary(errorhandling);
											if(find==1)
											{
											    printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_06);
											    return 0;
											}
											struct narytree *tempo;
											tempo=memAllocNode();
											temp->rightsibling->leftsibling=NULL;
											temp->parent->child=temp->rightsibling;
											tempo->mydes=temp->mydes;
						
											if(temp->child!=NULL)
											{
											    //temp->child->parent=NULL;
											    tempo->child=temp->child;
											    tempo->child->parent=tempo;
											    struct narytree *tempextra;
											    tempextra=tempo->child;
											    rightvalid=rightChildCheck(tempextra);
											    while(rightvalid==2)
											    {
												tempextra->rightsibling->parent=tempo;
												tempextra=tempextra->rightsibling;
											    }
											}
											else tempo->child=NULL;

											delete_bstnode(bst_root,temp->mydes->locationpath);
											free(temp);
											if(strcmp(dest_dir_path,"/")!=0)
											{
											    strcat(dest_dir_path,"/");
											}
											strcat(dest_dir_path,tempo->mydes->filename);
											strcpy(tempo->mydes->locationpath,dest_dir_path);
											int state=move_nary(tempo);
											if(state==1) printf("movedir_SUCCESS\n");
											return 1;



										    }
										   

										}


									    }
									}
								    }
								}
								}
								}
			
									else
									{
	
										printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_07);
									 }   




							}

   							 
							else
							 {
								printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_08);
							 }
        						
    						}
						else
						{
							printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_02);
						}
    					}
					else
					{
						printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_05);
					}

    				     }
				     else
				     {
					printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_01);
				     }	  
        				
    				}
				else
				{
					 printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_03);
				}
			 }	
			 else
			 {
				//---
				printf("movedir_FAILURE %s\n",ERR_VFS_MOVEDIR_04);
			 }
		}
		else
		{
			//error code 4
			printf("movedir_FAILURE %s\n", ERR_VFS_MOVEDIR_10);
		}
    	
	return collect;
}


